import { api } from "../ice/api";
import { sendSms } from "../../utils/notice/sms-yp";
import { genAppToken } from "../../utils/jwt";

const ip_sms_limit_2h = 12;
const next_sec = 60;

const userUtil = {
  sendVcode(mobile, code) {
    return sendSms(
      mobile,
      `【Tablo】您的验证码是${code}。如非本人操作，请忽略本短信`
    );
  },
  async checkIpVcode(ip) {
    const logNum = await api.getActLogs({
      _limit: 0,
      path: "login",
      act: "get-vcode",
      ip,
      createdAt: ">" + (Date.now() - 2 * 3600e3),
    });
    if (logNum > ip_sms_limit_2h) {
      throw "bad request";
    }
  },
};

export async function getVcode(body, userId, ip) {
  const { mobile } = body;
  if (!/^1\d{10}$/.test(mobile)) {
    throw "手机号不正确";
  }
  await userUtil.checkIpVcode(ip);
  let params = {
    mobile,
  };
  if (userId) {
    params.id = userId;
  }
  let user = await api.getUserInfo(params);
  if (!user || params.id) {
    user = await api.postUserInfo({
      ...params,
      mobile,
      ip,
    });
  }
  if (Date.now() - user.vcode_at < next_sec * 1e3) {
    throw "请稍后重试";
  }
  const vcode = Math.random().toString().substr(-4);
  await userUtil.sendVcode(mobile, vcode);
  api.postActLog({
    path: "login",
    act: "get-vcode",
    extra: { mobile, vcode },
    userId: user.id,
    ip,
  });
  await api.postUserInfo({
    id: user.id,
    vcode,
    vcode_at: Date.now(),
    ip,
    fail_times: 0,
  });
  return {
    id: user.id,
    next_sec,
  };
}

export async function checkVcode(body) {
  const { mobile, vcode } = body;
  if (!mobile || !vcode) {
    throw "缺少参数";
  }
  const user = await api.getUserInfo({
    mobile,
  });
  if (!user || !user.vcode) {
    throw "请先发送验证码";
  }
  const id = user.id;
  if (Date.now() - user.vcode_at > 10 * 60e3) {
    throw "验证码已过期";
  }
  if (user.fail_times > 5) {
    throw "验证次数超限";
  }
  if (vcode != user.vcode) {
    await api.postUserInfo({
      id,
      fail_times: user.fail_times + 1,
    });
    throw "验证码错误";
  }
  await api.postUserInfo({
    id,
    status: 2,
    vcode: null,
  });
  api.postActLog({
    path: "login",
    act: "vcode-ok",
    extra: body,
    userId: user.id,
  });
  return {
    id,
    mobile,
    token: genAppToken(id),
  };
}
